#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>

#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include <SD.h>

#include <Arduino_JSON.h>




#define STASSID "Galaxy"
#define STAPSK  "Asba1234"




String logname,datastring,payload ;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
String rxx;
String jsonString_to_server,jsonString_to_serial;
unsigned long last;
char send1[256];
char send2[256];

RTC_DS1307 rtc;
DateTime now;
File dataFile;



void setup() {

  Serial.begin(9600);
  Serial.println();
  Serial1.begin(9600);


  WiFi.mode(WIFI_STA);
  WiFi.begin(STASSID, STAPSK);

    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println("");
  Serial.print("Connected! IP address: ");
  Serial.println(WiFi.localIP());



 if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  

 // if (! rtc.isrunning()) {
  //  Serial.println("RTC is not running");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // rtc.adjust(DateTime(2019, 3, 18, 11, 36, 0));//yy:mm:dd:hh:mm:ss
 // }


   

    Serial.print("Initializing SD card...");


  if (!SD.begin(D8)) {
    Serial.println("Card failed, or not present");
 
  }else{ Serial.println("card initialized.");
  }

  

now = rtc.now();
Serial.print("Board Time --> ");
Serial.print(now.hour());Serial.print(':');Serial.println(now.minute());


}//setup





//baud rate is 9600 for serial comm
//you should send newline after serial send




void loop() {

//if(Serial.available()){
  
Serial.println("This is serial:"); 
Serial.println(Serial.available());
Serial.println("THis is Serial1:");
Serial.println(Serial1.available());
if(Serial1.available()>0||Serial.available()>0){
  rxx=Serial.readStringUntil('\n');
  Serial.readBytes(send1,256);
  Serial1.readBytes(send2,256);
  Serial.println(send1);
  Serial.println(send2);// to make sure that we have something coming in 
//}
Serial.println("afterSerial.available");
Parse_from_serial(send1);
storeonsd(rxx);
creat_json_to_server();
https_post(send1);
}


if (millis()-last>(60000*15)){
https_get();
Parse_from_server(payload);
storeonsd(payload);
creat_json_to_serial();
https_post(send1);
last=millis();
}



 
}//loop


void https_get(){

payload="no data";
  
    std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
    client->setInsecure();

    HTTPClient https;

    Serial.print("[HTTPS] begin...\n");
    if (https.begin(*client, "https://web.engr.oregonstate.edu/~rottek/currentschedule.php/echo/get/json")) {  // HTTPS

      Serial.print("[HTTPS] GET...\n");
      int httpCode = https.GET();


      if (httpCode > 0) {
        Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          payload = https.getString();
          Serial.println(payload);
        }
      } else {
        Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
      }

      https.end();
    } else {
      Serial.printf("[HTTPS] Unable to connect\n");
    }
}//get


//////////////////////////////////////////////////////////////////////////////////////////////////////////


void https_post(String toSend){

payload="no data";
  
    std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
    client->setInsecure();

    HTTPClient https;

    Serial.print("[HTTPS] begin...\n");
    if (https.begin(*client, "https://web.engr.oregonstate.edu/~rottek/remotedatainsert.php")) {  // HTTPS

      Serial.print("[HTTPS] POST...\n");
      int httpCode = https.POST(toSend);


      if (httpCode > 0) {
        Serial.printf("[HTTPS] POST... code: %d\n", httpCode);
        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          payload = https.getString();
          Serial.println(payload);
        }
      } else {
        Serial.printf("[HTTPS] POST.. failed, error: %s\n", https.errorToString(httpCode).c_str());
      }

      https.end();
    } else {
      Serial.printf("[HTTPS] Unable to connect\n");
    }
}//post


//////////////////////////////////////////////////////////////////////////////////////////////////////////


void creat_json_to_server(){
  JSONVar myObject;
  get_time();

  myObject["ID"] =" A";
  myObject["nodeID"] =" A";
  myObject["currentSchedule"] ="Morning Schedule";
  myObject["nodeOn"] ="yes";
  myObject["nodeOpen"] ="yes";
  myObject["error"] ="None";
  myObject["timestamp"] =datastring;
  

  Serial.print("myObject.keys() = ");
  Serial.println(myObject.keys());

  jsonString_to_server = JSON.stringify(myObject);

  Serial.print("JSON.stringify(myObject) = ");
  Serial.println(jsonString_to_serial);

  Serial.println();

 
  Serial.print("myObject = ");
  Serial.println(myObject);

  
}//creat
///////////////////////////////////////////////////////
void creat_json_to_serial(){
  JSONVar myObject;
  get_time();

  myObject["nodeID"] ="";
  myObject["currentSchedule"] ="";
  myObject["nodeOn"] ="";
  myObject["nodeOpen"] ="";
  myObject["error"] ="";
  myObject["timestamp"] =datastring;


  jsonString_to_serial = JSON.stringify(myObject);

  Serial.print("JSON.stringify(myObject) = ");
  Serial.println(jsonString_to_serial);

  Serial.println();

 
  Serial.print("myObject = ");
  Serial.println(myObject);

  
}//creat




void get_time(){
  
    now = rtc.now();    
    datastring="  ";
    datastring+=now.year();
    datastring+='-';
    datastring+=now.month();
    datastring+='-';
    datastring+=now.day();
    datastring+='(';
    datastring+=daysOfTheWeek[now.dayOfTheWeek()];
    datastring+=')';

    datastring+='\n';
    datastring+=now.hour();
    datastring+=':';
    datastring+=now.minute();
    datastring+=':';
    datastring+=now.second();
}//





void Parse_from_server(String input) {



  JSONVar myObject = JSON.parse(input);

  // JSON.typeof(jsonVar) can be used to get the type of the var
  if (JSON.typeof(myObject) == "undefined") {
    Serial.println("Parsing input failed!");
    return;
  }

  Serial.print("JSON.typeof(myObject) = ");
  Serial.println(JSON.typeof(myObject)); // prints: object




  // JSON vars can be printed using print or println
  Serial.print("myObject = ");
  Serial.println(myObject);

  Serial.println();
}




void Parse_from_serial(String input) {

  JSONVar myObject = JSON.parse(input);

  // JSON.typeof(jsonVar) can be used to get the type of the var
  if (JSON.typeof(myObject) == "undefined") {
    Serial.println("Parsing input failed!");
    return;
  }


  // JSON vars can be printed using print or println
  Serial.print("myObject = ");
  Serial.println(myObject);

  Serial.println();
}


void storeonsd(String datToSave){
    now = rtc.now();    
    Serial.print(now.year(), DEC);
    datastring="  ";
    datastring+=" > ";
    datastring+=now.year();
    Serial.print('/');
    datastring+='/';
    Serial.print(now.month(), DEC);
    datastring+=now.month();
    Serial.print('/');
    datastring+='/';
    Serial.print(now.day(), DEC);
    datastring+=now.day();
    Serial.print(" (");
    datastring+='(';
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    datastring+=daysOfTheWeek[now.dayOfTheWeek()];
    Serial.print(") ");
    datastring+=')';
    Serial.print(now.hour(), DEC);
    datastring+=now.hour();
    Serial.print(':');
    datastring+=':';
    Serial.print(now.minute(), DEC);
    datastring+=now.minute();
    Serial.print(':');
    datastring+=':';
    Serial.print(now.second(), DEC);
    datastring+=now.second();
    Serial.println();
    Serial.println();
    datastring+=",  payload :  ";datastring+=datToSave;datastring+="   \n\n";   
    
    

   dataFile = SD.open("logfile.txt", FILE_WRITE);
   dataFile.println(datastring);
   dataFile.close();

}
